module my_mpi
  include   'mpif.h'
  integer   :: MyPE, MasterPE, NumPEs
end module my_mpi

module logs
  integer*4 :: logunit
  character(len=256) :: logfile,mystring
end module logs

module arg_module
  character(len=256) :: arg_snap
  integer*4          :: isnap
  character(len=256) :: arg_frame
  integer*4          :: iframe
#ifndef USE_CAM_FILE
  character(len=256) :: arg_x
  character(len=256) :: arg_y
  character(len=256) :: arg_z
  character(len=256) :: arg_vx
  character(len=256) :: arg_vy
  character(len=256) :: arg_vz
  character(len=256) :: arg_L1
  character(len=256) :: arg_L2
  character(len=256) :: arg_L3
#ifdef USE_EIGENVECTORS
  character(len=256) :: arg_xprime_x
  character(len=256) :: arg_xprime_y
  character(len=256) :: arg_xprime_z
  character(len=256) :: arg_yprime_x
  character(len=256) :: arg_yprime_y
  character(len=256) :: arg_yprime_z
  character(len=256) :: arg_zprime_x
  character(len=256) :: arg_zprime_y
  character(len=256) :: arg_zprime_z
#else
  character(len=256) :: arg_theta
  character(len=256) :: arg_phi
  character(len=256) :: arg_psi
#endif
#endif
end module arg_module

module parameter_module
  ! Ensure that all tags have the same length as longest tag
  ! This is an F90 feature; array constructors must have same length
  !logical, dimension(nparams)           :: read_param = .false.
#ifdef CUBE
  integer*4, parameter                  :: nparams = 12
  logical, dimension(nparams)           :: read_param = .false.
  character(len=64), dimension(nparams) :: ParamTags = (/'CameraFile  ', &
                                                         'SnapDir     ', &
                                                         'SnapBase    ', &
                                                         'ObsDir      ', &
                                                         'ObsBase     ', &
                                                         'HsmlDir     ', &
                                                         'HsmlBase    ', &
                                                         'OutputDir   ', &
                                                         'VarFile     ', &
                                                         'nx          ', &
                                                         'ny          ',& 
                                                         'nz          '/)
#else
  integer*4, parameter                  :: nparams = 11
  logical, dimension(nparams)           :: read_param = .false.
  character(len=64), dimension(nparams) :: ParamTags = (/'CameraFile  ', &
                                                         'SnapDir     ', &
                                                         'SnapBase    ', &
                                                         'ObsDir      ', &
                                                         'ObsBase     ', &
                                                         'HsmlDir     ', &
                                                         'HsmlBase    ', &
                                                         'OutputDir   ', &
                                                         'VarFile     ', &
                                                         'nx          ', &
                                                         'nz          '/)
#endif

  type param_type
     character(len=256) :: CameraFile
     character(len=256) :: SnapDir
     character(len=256) :: SnapBase
     character(len=256) :: ObsDir
     character(len=256) :: ObsBase
     character(len=256) :: HsmlDir
     character(len=256) :: HsmlBase
     character(len=256) :: Catalogue
     character(len=256) :: OutputDir
     character(len=256) :: VarFile
     integer*4          :: nx
#ifdef CUBE
     integer*4          :: ny
#endif
     integer*4          :: nz

  end type param_type
  type(param_type)      :: params
end module parameter_module

module camera_module
  real*4 :: x0
  real*4 :: y0
  real*4 :: z0
#ifdef VELOCITY
  real*4 :: vx0
  real*4 :: vy0
  real*4 :: vz0
#endif
  real*4 :: L(3)
#ifdef USE_EIGENVECTORS
  real*8 :: xprime(3)
  real*8 :: yprime(3)
  real*8 :: zprime(3)
#else
  real*4 :: theta
  real*4 :: phi
  real*4 :: psi
#endif
#ifdef USE_CAM_FILE
  integer*4           :: NumFramesCamFile 
  integer*4, allocatable :: cam_Frames(:)
  real*4,    allocatable :: cam_x(:)
  real*4,    allocatable :: cam_y(:)
  real*4,    allocatable :: cam_z(:)
#ifdef VELOCITY
  real*4,    allocatable :: cam_vx(:)
  real*4,    allocatable :: cam_vy(:)
  real*4,    allocatable :: cam_vz(:)
#endif
  real*4,    allocatable :: cam_Lx(:)
  real*4,    allocatable :: cam_Ly(:)
  real*4,    allocatable :: cam_Lz(:)
#ifdef USE_EIGENVECTORS
  real*8,    allocatable :: cam_xprime(:,:)
  real*8,    allocatable :: cam_yprime(:,:)
  real*8,    allocatable :: cam_zprime(:,:)
#else
  real*4,    allocatable :: cam_theta(:)
  real*4,    allocatable :: cam_phi(:)
  real*4,    allocatable :: cam_psi(:)
#endif
#endif
end module camera_module

module myfiles
  character(len=256) :: paramfile,camerafile,rangefile
  character(len=256) :: snapdir,snapfile,infile
  character(len=256) :: popsyndir,popsynfile
  character(len=256) :: catalogue
  character(len=256) :: out_dens,out_vx,out_vy,out_vz,out_metal
  character(len=256) :: outdir
  logical :: popsyn
end module myfiles

module exchange
  integer*4 :: NumRetain
  integer*4 :: NumImport
  integer*4 :: NumExport
  integer*4, allocatable :: DestinationPE(:)
  integer*4, allocatable :: NumImportPE(:)
  integer*4, allocatable :: NumExportPE(:)
  integer*4, allocatable :: ImportOffset(:)
  integer*4, allocatable :: ExportOffset(:)
  integer*4, allocatable :: ExchangeMatrix(:)
  real*4, allocatable    :: ImportBuf_Int(:)
  character, allocatable :: ImportBuf(:)
  character, allocatable :: ExportBuf(:)
end module exchange

module smoothing_variables                   
  integer*4 :: nvars
  integer*4, dimension(0:5) :: nvar_by_type = 0
  integer*4, parameter :: nvars_max = 100
  character(len=256), dimension(1:nvars_max)     :: var_tmp
  character(len=256), dimension(0:5,1:nvars_max) :: var
end module smoothing_variables

module grid
  integer*4           :: ngrids, nnorm, nzlocal, nzmaster
  integer*4           :: istart,iend,NumFrames,NumFramesCamFile
  integer*4           :: ixyz_grid, ix_grid, iy_grid, iz_grid
  real*4              :: PixelSize
  real*4              :: GridExtent(2,3), LocalExtent(2,3)
  real*4              :: GhostExtent(2)
#ifdef CUBE
  real*4              :: CellSize(3)
  real*4, allocatable :: Value(:,:,:)
  real*4, allocatable :: ValueQuantity(:,:,:,:)
#else
  real*4              :: CellSize(2)
  real*4, allocatable :: Value(:,:)
  real*4, allocatable :: ValueQuantity(:,:,:)
#endif
  real*4              :: temp_min,temp_max,temp_sum
  real*4              :: ValueMin,ValueMax,ValueSum
  real*4, allocatable :: ValueQuantityMin(:),ValueQuantityMax(:),ValueQuantitySum(:)
end module grid

module particles
  integer*4                            :: NumPart_Local
  integer*4, allocatable, dimension(:) :: NumPart_ByPE,NumGhost_ByPE
  integer*4, dimension(6)              :: iSpecies_list(0:5)
  integer*4, allocatable               :: indx(:)
  real*4,    allocatable               :: readCoordinates(:,:)
#ifdef VELOCITY
  real*4,    allocatable               :: readVelocity(:,:)
#endif
  real*4,    allocatable               :: readMass(:)
  integer*4, allocatable               :: readParticleIDs(:)
  real*4,    allocatable               :: readSmoothingLength(:)
  real*4,    allocatable               :: readEoS(:)
  real*4,    allocatable               :: readSmoothVar(:,:)
  real*4,    allocatable               :: Coordinates(:,:)
#ifdef VELOCITY
  real*4, allocatable                  :: Velocity(:,:)
#endif
  real*4, allocatable                  :: Mass(:)
  integer*4, allocatable               :: ParticleIDs(:)
  real*4, allocatable                  :: SmoothingLength(:)
  real*4, allocatable                  :: EoS(:)
  real*4, allocatable                  :: SmoothVar(:,:)
  real*4, allocatable                  :: Ghost_Coordinates(:,:)
#ifdef VELOCITY                        
  real*4, allocatable                  :: Ghost_Velocity(:,:)
#endif                                 
  real*4, allocatable                  :: Ghost_Mass(:)
  real*4, allocatable                  :: Ghost_SmoothingLength(:)
  real*4, allocatable                  :: Ghost_EoS(:)
  real*4, allocatable                  :: Ghost_SmoothVar(:,:)
end module particles

module header
  integer*4 :: NumPart_ThisFile(0:5), NumPart_Total(0:5),NumPart_Total_HighWord(0:5)
  integer*4 :: NumFilesPerSnapshot,Flag_SFR,Flag_Cooling,Flag_StellarAge,Flag_Metals,Flag_Feedback
  real*8 :: MassTable(6), Time_GYR, ExpansionFactor, Redshift, BoxSize, Omega0
  real*8 :: OmegaBaryon, OmegaLambda, HubbleParam
end module header

module units_and_constants
  type units_data
     real*8 :: UnitLength_in_cm
     real*8 :: UnitMass_in_g
     real*8 :: UnitVelocity_in_cm_per_s
     real*8 :: UnitDensity_in_cgs
     real*8 :: UnitEnergy_in_cgs
     real*8 :: UnitPressure_in_cgs
     real*8 :: UnitTime_in_s
  end type units_data
  type constants_data
     real*8 :: PI
     real*8 :: GAMMA
     real*8 :: GRAVITY
     real*8 :: SOLAR_MASS
     real*8 :: SOLAR_LUM
     real*8 :: RAD_CONST
     real*8 :: AVOGADRO
     real*8 :: BOLTZMANN
     real*8 :: GAS_CONST
     real*8 :: C
     real*8 :: PLANCK
     real*8 :: CM_PER_MPC
     real*8 :: PROTONMASS
     real*8 :: ELECTRONMASS
     real*8 :: ELECTRONCHARGE
     real*8 :: HUBBLE
     real*8 :: T_CMB0
     real*8 :: SEC_PER_MEGAYEAR
     real*8 :: SEC_PER_YEAR
     real*8 :: STEFAN
     real*8 :: THOMPSON
     real*8 :: EV_TO_ERG
     real*8 :: Z_Solar
  end type constants_data
  type(units_data) :: Units
  type(constants_data) :: Constants
  real*8            :: Dcom                   ! Comoving distance 
  real*8            :: arcsec_per_radian      ! ~1/206265
  real*8            :: comoving_angular_scale ! kpc/arcsec
  real*8            :: physical_angular_scale ! kpc/arcsec
end module units_and_constants

module hsmlfile
  type hsmltype
     integer*4, allocatable, dimension(:) :: ParticleIDs
     real*4,    allocatable, dimension(:) :: SmoothingLength
  end type hsmltype
  type(hsmltype) hsml
end module hsmlfile

module gadget3_bg_variables_module
  integer*4, parameter :: n_bg_vars = 34
  character(len=512), dimension(n_bg_vars) :: bg_vars = (/'AExpMaximumEntropy',&
                                                          'AExpMaximumTemperature',&
                                                          'Coordinates',&
                                                          'Density',&           
                                                          'ElementAbundance/Carbon',&
                                                          'ElementAbundance/Helium',&  
                                                          'ElementAbundance/Hydrogen',&  
                                                          'ElementAbundance/Iron',&  
                                                          'ElementAbundance/Magnesium',&  
                                                          'ElementAbundance/Neon',&  
                                                          'ElementAbundance/Nitrogen',&  
                                                          'ElementAbundance/Oxygen',&  
                                                          'ElementAbundance/Silicon',&  
                                                          'InternalEnergy',&      
                                                          'IronFromSNIa',&        
                                                          'Mass',&          
                                                          'MaximumEntropy',&
                                                          'MaximumTemperature',&       
                                                          'Metallicity',&    
                                                          'MetallicityWeightedRedshift',&
                                                          'OnEquationOfState',&
                                                          'ParticleIDs',&     
                                                          'RateOfChangeOfEntropy',&
                                                          'SmoothedElementAbundance',& 
                                                          'SmoothedIronFromSNIa',&
                                                          'SmoothedMetallicity',&  
                                                          'SmoothingLength',&   
                                                          'StarFormationRate',&       
                                                          'Temperature',&     
                                                          'Velocity',&
                                                          'InitialMass',&
                                                          'StellarFormationTime',&
							  'Density_HI',&
							  'Mass_HI'/)
end module gadget3_bg_variables_module
